using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Playables;
using UnityEngine.Timeline;

public class VSBasicClip : PlayableAsset, ITimelineClipAsset, ISerializationCallbackReceiver
{
    public ClipCaps clipCaps => ClipCaps.None;

    [LabelText("索引")] public int curClipIndex;
    [LabelText("根节点(仅在Director预览下需要)")] public GameObject owner;
    [LabelText("函数驱动")] public bool dirveByFunc = false;
    public VSBasicBehaviour template = new VSBasicBehaviour();

    //注意此template 和 getbehaviour 得到的完全是两个实例, 详细看Create中的逻辑
    //Director会在Awake和Editor环境都调用该Playable , 相当于有完整的生命周期

    public override Playable CreatePlayable(PlayableGraph graph, GameObject owner)
    {
        VActProcessor processor = owner.GetComponent<VActProcessor>();
        template.InitBehaviour(processor);
        template.runtimeOnDirector = true;
        var p = ScriptPlayable<VSBasicBehaviour>.Create(graph, template);
        return p;
    }

    public ScriptPlayable<VSBasicBehaviour> CreatePlayableManual(PlayableGraph graph, GameObject owner)
    {
        VActProcessor processor = owner.GetComponent<VActProcessor>();
        template.InitBehaviour(processor);
        template.runtimeOnDirector = false;
        var p = ScriptPlayable<VSBasicBehaviour>.Create(graph, template);
        return p;
    }




    [Button("裁切动画到原始长度")]
    // [ShowIf("@parentTrack.trackType==VSClipType.Animation")]
    public void CutClip()
    {
        selfTimelineClip.duration = template.AnimationHandler_Data.clip.averageDuration;
    }



    #region Locate
    [HideInInspector] public VSBasicTrack parentTrack;
    [HideInInspector] public TimelineClip selfTimelineClip;

    //这里应该是根据Owner一步定位全员散播的 , 但是还有其他物体的编排怎么办, 不会, 加个锚点就行了
    //也就是说这里的Sync并不完全安全, 等待改进
    public void OnBeforeSerialize()
    {
        GloablTimelineSync();
    }
    private void GloablTimelineSync()
    {
        //可以加缓存来优化性能,但是就几个的话还是遍历然后单个矫正了
        if (owner == null) return;
        var director = owner.GetComponentInChildren<PlayableDirector>();
        var tml = (TimelineAsset)director.playableAsset;

        foreach (var track in tml.GetRootTracks())
        {
            var clips = track.GetClips();
            if (track.name == "Warehouse") continue;

            foreach (var timelineClip in clips)
            {
                var vsbc = timelineClip.ToClip();
                vsbc.owner = owner;
                if (vsbc == this)
                {
                    vsbc.parentTrack = track as VSBasicTrack;
                    vsbc.selfTimelineClip = timelineClip;
                    vsbc.template.clipType = parentTrack.trackType;
                    if(timelineClip.displayName == "VSBasicClip")
                    {
                        timelineClip.displayName = parentTrack.name;
                    }
                }

            }
        }

    }
    public void OnAfterDeserialize() { }
    #endregion

}


public static class VSBasicClipExtension
{
    public static VSBasicClip ToClip(this TimelineClip oriclip)
    {
        return oriclip.asset as VSBasicClip;
    }

    public static VSBasicBehaviour ToBehavior(this TimelineClip oriclip)
    {
        return (oriclip.asset as VSBasicClip).template;
    }

}